package cn.touna.jss.modules.third.cardniu.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * Created by zhangwenzheng(wenzheng_zhang@suishouji.com) 合作方调用卡牛方接口
 * 
 * @Date 2018-3-26 0026.
 */
public class OuterInvoker {
	private static Logger logger = LoggerFactory.getLogger(OuterInvoker.class);
	private static final String[] hexDigits = new String[] { "0", "1", "2",
			"3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

	private OuterInvoker() {
	}

	/**
	 * 合作方调用卡牛获取用户银行卡信息接口demo
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
//		String baseUrl = "http://tg.feidee.net/cardniuloan/outer/activate/";
//		String url = baseUrl + "user/bank/info";
		String url ="http://tg.feidee.net/test/cardniuloan/outer/activate/user/device/info";
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("version", "1.0.0");
		jsonObject.put("userId", "2422692");
//		jsonObject.put("activateId", "666");
		jsonObject.put("activateId", "123456");
		// 合作方跟卡牛方约定的salt-key
		String salt = "";
		// productCode 为卡牛方给合作方的产品code
		String productCode = "paymax";
		String sid = jsonObject.toJSONString();
		String pouchMd5 = MD5Encode(
				MD5Encode(jsonObject.toJSONString(), "utf-8").toUpperCase()
						+ salt, "utf-8").toUpperCase();
		Map heardMap = new HashMap();
		heardMap.put("productCode", productCode);
		heardMap.put("sign", pouchMd5);
		Map bodyMap = new HashMap();
		bodyMap.put("sid", sid);
		String msg = requestUrlByPost(url, bodyMap, heardMap, 5000, 5000);
		System.out.println(msg);
	}

	/**
	 * MD5 验证
	 * 
	 * @param origin
	 * @param charsetname
	 * @return
	 */
	public static String MD5Encode(String origin, String charsetname) {
		String resultString = null;
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			if (charsetname != null && !"".equals(charsetname)) {
				resultString = byteArrayToHexString(md.digest(origin
						.getBytes(charsetname)));
			} else {
				resultString = byteArrayToHexString(md
						.digest(origin.getBytes()));
			}
		} catch (Exception var4) {
			logger.error("error in MD5Encode :{}", var4);
		}
		return resultString;
	}

	private static String byteArrayToHexString(byte[] b) {
		StringBuilder resultSb = new StringBuilder();
		for (int i = 0; i < b.length; ++i) {
			resultSb.append(byteToHexString(b[i]));
		}
		return resultSb.toString();
	}

	private static String byteToHexString(byte b) {
		int n = b;
		if (b < 0) {
			n = b + 256;
		}
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

	/**
	 * post 请求
	 * 
	 * @param urlStr
	 * @param bodyParams
	 *            85
	 * @param headerParams
	 * @param connectTimeOut
	 * @param socketTimeOut
	 * @return
	 * @throws Exception
	 */
	public static String requestUrlByPost(String urlStr,
			Map<String, String> bodyParams, Map<String, String> headerParams,
			int connectTimeOut, int socketTimeOut) throws Exception {
		CloseableHttpClient httpClient = generateClientByUrlProtocol(urlStr);
		RequestConfig requestConfig = RequestConfig.custom()
				.setConnectTimeout(connectTimeOut)
				.setSocketTimeout(socketTimeOut).build();
		HttpPost httpPost = new HttpPost(urlStr);
		httpPost.setConfig(requestConfig);
		if (Objects.nonNull(bodyParams)) {
			List<NameValuePair> nvps = new ArrayList<>();
			// bodyParams.entrySet().stream().forEach(entry->{
			// nvps.add(new
			// BasicNameValuePair(entry.getKey(),entry.getValue()));
			// });
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
		}
		if (Objects.nonNull(headerParams)) {
			// headerParams.entrySet().stream().forEach(
			// entry->{
			// httpPost.setHeader(entry.getKey(),entry.getValue());
			// });
		}
		HttpResponse response = httpClient.execute(httpPost);
		HttpEntity entity = response.getEntity();
		StringBuffer sb = new StringBuffer();
		try (InputStream is = entity.getContent();
				BufferedReader br = new BufferedReader(new InputStreamReader(
						is, "utf-8"))) {
			String content;
			while ((content = br.readLine()) != null) {
				sb.append(content);
			}
		}
		return sb.toString();
	}
	

	private static CloseableHttpClient createHttpsClient() throws Exception {
		SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
				new TrustStrategy() {
					@Override
					public boolean isTrusted(
							X509Certificate[] x509Certificates, String s)
							throws CertificateException {
						return true;
					}
				}).build();
		return HttpClients
				.custom()
				.setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext))
				.build();
	}
	
	

	private static CloseableHttpClient generateClientByUrlProtocol(String urlStr)
			throws Exception {
		if (urlStr.startsWith("https")) {
			return createHttpsClient();
		}
		return HttpClients.createDefault();
	}
	

	/**
	 * 关闭流
	 * 
	 * @param is
	 * @param br
	 */
	private static void closeStream(InputStream is, BufferedReader br) {
		try {
			if (is != null) {
				is.close();
			}
			if (br != null) {
				br.close();
			}
		} catch (IOException var3) {
			logger.error("closeStream error");
		}
	}

}
